#pragma once
#include   <vcclr.h>  
#include <string.h>

#include "ThostFtdcMdApi.h"
#include "StructWrapper.h"
#include "ThostFtdcMdSpiWrapper.h"
#include "Tool.h"

using namespace System;

namespace SQMarketApiWrapper
{
	public ref class CThostFtdcMdApiWrapper
	{
	private:
		CThostFtdcMdApi *m_Impl;
		CThostFtdcMdSpi *m_Spi;

		void Initial(String^ path)
		{
			if(
				path->IsNullOrEmpty(path))
			{
				m_Impl=CThostFtdcMdApi::CreateFtdcMdApi();
			}
			else
			{
				char* cpath = StringToCharPoint(path);
				m_Impl = CThostFtdcMdApi::CreateFtdcMdApi(cpath);
				FreeHGlobalChar(cpath);
			}
			m_Spi = NULL;
		}

	public:
		CThostFtdcMdApiWrapper()
		{
			String^ s;
			Initial(s->Empty);
		}
		CThostFtdcMdApiWrapper(String^ path)
		{
			Initial(path);
		}		
		~CThostFtdcMdApiWrapper()
		{
			if (m_Impl)
			{
				m_Impl->RegisterSpi(NULL);
				m_Impl->Release();
				m_Impl = NULL;
			}
			if(m_Spi != NULL)
			{
				delete m_Spi;
				m_Spi = NULL;
			}
		}
	public:
		void Release()
		{
			if(m_Impl != NULL)
			{
				m_Impl->Release();
				m_Impl = NULL;
			}
		}
		void Init()
		{
			if(m_Impl != NULL)
			{
				m_Impl->Init();
			}
		}
		void Join()
		{
			if(m_Impl != NULL)
			{
				m_Impl->Join();
			}
		}
		String^ GetTradingDay()
		{
			if(m_Impl != NULL)
			{
				char* date = (char*)m_Impl->GetTradingDay();
				return StringFromCharPoint(date);	
			}
			return "";
		}
		void RegisterFront(String^ frontAddress)
		{
			if(m_Impl != NULL)
			{
				char* addr = StringToCharPoint(frontAddress);
				m_Impl->RegisterFront(addr);
				FreeHGlobalChar(addr);
			}
		}

		int ReqUserLogin(CThostFtdcReqUserLoginFieldWrapper^ field, int nRequestId)
		{
			return m_Impl->ReqUserLogin(field->m_Impl, nRequestId);
		}

		int ReqUserLogout(CThostFtdcUserLogoutFieldWrapper^ field, int nRequestId)
		{
			return m_Impl->ReqUserLogout(field->m_Impl, nRequestId);
		}

		int SubscribeMarketData(array<String^>^ instruments)
		{
			int count = instruments->Length;
			char** temp = new char*[count];
			for(int i=0; i<count; i++)
			{
				temp[i] = StringToCharPoint(instruments[i]);
			}
			return m_Impl->SubscribeMarketData(temp, count);
		}

		int UnSubscribeMarketData(array<String^>^ instruments)
		{
			int count = instruments->Length;
			char** temp = new char*[count];
			for(int i=0; i<count; i++)
			{
				temp[i] = StringToCharPoint(instruments[i]);
			}
			return m_Impl->UnSubscribeMarketData(temp, count);
		}

		void RegisterSpi(CThostFtdcMdSpiWrapper^ spi)
		{
			if(spi)
			{
				SpiBridge* bridge = new SpiBridge(spi);
				m_Impl->RegisterSpi(bridge);
			}
			else
			{
				m_Impl->RegisterSpi(NULL);
			}
		}
	};	
}
